﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using FinanSoft.Utilities;
using FinanSoft.Entities;
using FinanSoft.BusinessLayer;

namespace FinanSoft.PresentacionComprasyVentas
{
    public partial class frmOrden : Form
    {
        private int[] _currencyIds;
        private List<int> _documentCodes;
        private List<string> _docTypes;
        private int[] _auxAccIds;
        private List<DocDetail> _docDetails;
        private double _totalAmount;
        private double _subTotalAmount;
        private double _taxAmount;

        public frmOrden()
        {
            InitializeComponent();
            _docDetails = new List<DocDetail>();
            _totalAmount = 0;
            txtAntesImp.Text = "$ 0.00";
            txtMontoImp.Text = txtAntesImp.Text;
            txtTotal.Text = txtMontoImp.Text;
            _subTotalAmount = 0;
            _taxAmount = 0;
            cmbDoc.Items.Add("Ninguno");
            fillComboBoxMoney();
            fillComboBoxTypeDoc();
        }

        //*********************************** Fill Combo Box ********************************

        // Método para llenar el combobox de monedas
        public void fillComboBoxMoney() 
        {
            int selectedId = Constants.INVALID_ID;
            List<Currency> addedCurrencies = MoneyManager.GetInstance().GetAddedCurrencies();
            _currencyIds = new int[addedCurrencies.Count + 2];
            for (int currencyIndex = 0; currencyIndex < addedCurrencies.Count; currencyIndex++)
            {
                _currencyIds[currencyIndex] = addedCurrencies[currencyIndex].Id;
                cmbMoneda.Items.Add(addedCurrencies[currencyIndex].Name);
            }
            Currency sys = MoneyManager.GetInstance().SystemCurrency;
            _currencyIds[_currencyIds.Length - 2] = sys.Id;
            cmbMoneda.Items.Add(sys.Name);
            Currency local = MoneyManager.GetInstance().LocalCurrency;
            _currencyIds[_currencyIds.Length - 1] = local.Id;
            cmbMoneda.Items.Add(local.Name);
            if (selectedId != Constants.INVALID_ID)
                cmbMoneda.SelectedIndex = selectedId;
            else
                cmbMoneda.SelectedIndex = cmbMoneda.Items.Count - 1;
        }

        //Método para llenar el combobox de Proveedores y Clientes
        public void fillComboProviderClient()
        {
            Hashtable auxAccountingTable = AuxiliaryAccountManager.GetInstance().GetAuxiliarAccountsList();
            _auxAccIds = new int[auxAccountingTable.Count];
            int auxIndex = 0;
            String acronimo = cmbTipoDoc.Text;
            if ((acronimo.Equals("OC")) || (acronimo.Equals("EM")) || (acronimo.Equals("FP")))
            {
                foreach (AuxiliarAccount auxAccount in auxAccountingTable.Values)
                    if (auxAccount.AccountType == Constants.AuxiliarAccountType.provider)
                    {
                        cmbName.Items.Add(auxAccount.Name);
                        _auxAccIds[auxIndex++] = auxAccount.AccountID;
                    }
            }
            else if (acronimo.Equals("OV") || acronimo.Equals("EE") || acronimo.Equals("FC") || acronimo.Equals("NC"))
            {
                foreach (AuxiliarAccount auxAccount in auxAccountingTable.Values)
                    if (auxAccount.AccountType == Constants.AuxiliarAccountType.client)
                    {
                        cmbName.Items.Add(auxAccount.Name);
                        _auxAccIds[auxIndex++] = auxAccount.AccountID;
                    }
            }
            if (cmbName.Items.Count != Constants.INVALID_ID)
                cmbName.SelectedIndex = 0;
        }

        //Método para llenar el comobobox de Tipos de Documentos
        public void fillComboBoxTypeDoc()
        {
            List<DocType> typeDocs = DocumentTypeManager.GetInstance().GetDocTypes();
            foreach (DocType typeDoc in typeDocs)
                if ((typeDoc.Name == "OC") || (typeDoc.Name == "OV") || (typeDoc.Name == "EM") || (typeDoc.Name == "EE") || (typeDoc.Name == "FP") || (typeDoc.Name == "FC") || (typeDoc.Name == "NC"))
                    cmbTipoDoc.Items.Add(typeDoc.Name);
            cmbTipoDoc.SelectedIndex = 0;
        }

        /// <summary>
        /// Llena el combo box de posibles documentos previos con un tipo específico de documento
        /// </summary>
        /// <param name="docTypeName"></param>
        /// <param name="docTypeAbbreviation"></param>
        private void fillDocByType(string docTypeName, string docTypeAbbreviation)
        {
            List<int> documentList = BuySaleManager.GetInstance().GetDocUncancelled(docTypeAbbreviation);
            foreach (int code in documentList)
            {
                cmbDoc.Items.Add(docTypeName + " - " + code.ToString("000000"));
                _documentCodes.Add(code);
                _docTypes.Add(docTypeAbbreviation);
            }
        }

        //Método para llenar el combobox de Documentos
        //Todavia no c si van a queda como acronimos o mejor como nombres completos.
        public void fillComboBoxDocs(String acronimo) 
        {
            cmbDoc.Items.Clear();
            cmbDoc.Items.Add("Ninguno");
            _documentCodes = new List<int>();
            _docTypes = new List<string>();
            _documentCodes.Add(Constants.INVALID_ID);
            _docTypes.Add("");
            if (acronimo == Constants.OC_ACCOUNTING_ENTRY)
            {
                labelType.Text = "Proveedores:";
                this.Text = "Orden de Compras";
                lblFechaEntrega.Text = "Fecha de Entrega";
                cmbDoc.Enabled = false;
            }
            else if (acronimo == Constants.OV_ACCOUNTING_ENTRY)
            {
                labelType.Text = "Clientes:";
                this.Text = "Orden de Venta";
                lblFechaEntrega.Text = "Fecha de Entrega";
                cmbDoc.Enabled = false;

            }
            else if (acronimo == Constants.EM_ACCOUNTING_ENTRY)
            {
                cmbDoc.Enabled = true;
                labelType.Text = "Proveedores:";
                this.Text = "Entrada de Mercancias Compras";
                lblFechaEntrega.Text = "Fecha de Vencimiento";
                fillDocByType("Orden de compra", Constants.OC_ACCOUNTING_ENTRY);
            }
            else if (acronimo == "EE")
            {
                cmbDoc.Enabled = true;
                labelType.Text = "Clientes:";
                this.Text = "Entrega de Mercancias Ventas";
                lblFechaEntrega.Text = "Fecha de Vencimiento";
                fillDocByType("Orden de venta", Constants.OV_ACCOUNTING_ENTRY);
            }
            else if (acronimo == "FP")
            {
                cmbDoc.Enabled = true;
                labelType.Text = "Proveedores:";
                this.Text = "Factura de Proveedores";
                lblFechaEntrega.Text = "Fecha de Vencimiento";
                fillDocByType("Orden de compra", Constants.OC_ACCOUNTING_ENTRY);
                fillDocByType("Entrada de mercancías", Constants.EM_ACCOUNTING_ENTRY);
            }
            else if (acronimo == "FC")
            {
                cmbDoc.Enabled = true;
                labelType.Text = "Clientes:";
                lblFechaEntrega.Text = "Fecha de Vencimiento";
                this.Text = "Factura de Clientes";
                fillDocByType("Orden de venta", Constants.OV_ACCOUNTING_ENTRY);
                fillDocByType("Entrega de mercancías", Constants.EE_ACCOUNTING_ENTRY);
            }
            else if (acronimo == "NC")
            {
                cmbDoc.Enabled = false;
                labelType.Text = "Clientes:";
                lblFechaEntrega.Text = "Fecha de Vencimiento";
                this.Text = "Notas de Crédito";
            }
            cmbDoc.SelectedIndex = 0;
            fillPreviousDoc();
        }

        public void AddItem(Item addedItem, StoreRoom store, double quantity, double cost, Tax tax)
        {
            _docDetails.Add(new DocDetail(addedItem, store, quantity, cost, tax));
            string currencySymbol = "";
            if (cmbMoneda.SelectedIndex != Constants.INVALID_ID)
                currencySymbol = MoneyManager.GetInstance().GetCurrency(_currencyIds[cmbMoneda.SelectedIndex]).Symbol;
            ItemStoreRoomInfo storeInfo = addedItem.GetStoreRoomInfo(store.Id);
            double subtotalAmount = Math.Round(quantity * cost, 2);
            double taxAmount = Math.Round(subtotalAmount * tax.Porcentaje, 2);
            gridArticulos.Rows.Add( new object[] 
                {addedItem.CodArticulo, addedItem.Descripción, 
                quantity, currencySymbol + " " + cost.ToString(), tax.Nombre, currencySymbol + " " + (subtotalAmount + taxAmount).ToString(), store.Name});
            updateTotals(taxAmount, subtotalAmount, currencySymbol);
        }

        private void DeleteItem()
        {
            int currentIndex = gridArticulos.CurrentRow.Index;
            if(currentIndex != Constants.INVALID_ID && currentIndex < _docDetails.Count)
            {
                gridArticulos.Rows.RemoveAt(currentIndex);
                DocDetail oldDetail = _docDetails[currentIndex];
                _docDetails.RemoveAt(currentIndex);
                double subtotalAmount = Math.Round(oldDetail.Quantity * oldDetail.UnitCost, 2);
                double taxAmount = Math.Round(subtotalAmount * oldDetail.Tax.Porcentaje, 2);
                string currencySymbol = "";
                if (cmbMoneda.SelectedIndex != Constants.INVALID_ID)
                    currencySymbol = MoneyManager.GetInstance().GetCurrency(_currencyIds[cmbMoneda.SelectedIndex]).Symbol;
                updateTotals(-taxAmount, -subtotalAmount, currencySymbol);
            }
        }

        /// <summary>
        /// Actualiza la información que se despliegue sobre el subtotal de la factura, el monto de impuestos y el monto total
        /// </summary>
        /// <param name="taxTotal"></param>
        /// <param name="subTotal"></param>
        /// <param name="symbol"></param>
        public void updateTotals(double taxTotal, double subTotal, string symbol)
        {
            _subTotalAmount += subTotal;
            _taxAmount += taxTotal;
            _totalAmount += subTotal + taxTotal;
            txtAntesImp.Text = symbol + " " + _subTotalAmount.ToString("0.00");
            txtMontoImp.Text = symbol + " " + _taxAmount.ToString("0.00");
            txtTotal.Text = symbol + " " + _totalAmount.ToString("0.00");
        }

        //Metodo para llenar la tabla
        public void fillPreviousDoc()
        {
            gridArticulos.Rows.Clear();
            _docDetails = new List<DocDetail>();
            _subTotalAmount = 0;
            _totalAmount = 0;
            _taxAmount = 0;
            if (cmbDoc.SelectedIndex > 0)
            {
                int baseDocCode = _documentCodes[cmbDoc.SelectedIndex];
                string docType = _docTypes[cmbDoc.SelectedIndex];
                Document getDoc = BuySaleManager.GetInstance().GetDocumentFor(baseDocCode, docType);
                foreach (DocDetail detail in getDoc.detalleDoc)
                {
                    AddItem(detail.Item, detail.StoreRoom, detail.Quantity, detail.UnitCost, detail.Tax);
                    cmbMoneda.SelectedIndex = Array.IndexOf(_currencyIds, getDoc.IdMoneda);
                    cmbName.SelectedIndex = Array.IndexOf(_auxAccIds, getDoc.IdCuentaAuxiliar);
                }
                cmbMoneda.Enabled = false;
                cmbName.Enabled = false;
            }
            else
            {
                cmbMoneda.Enabled = true;
                cmbName.Enabled = true;
                txtAntesImp.Text = "$ 0.00";
                txtMontoImp.Text = txtAntesImp.Text;
                txtTotal.Text = txtMontoImp.Text;
            }
        }

        private void btnSalir_Click(object sender, EventArgs e)
        {
            Close();
        }


        private void btnAgregarArt_Click(object sender, EventArgs e)
        {
            // Cargamos y mostramos el formulario Agregar Producto
            frmAgregarArticulo frmAgregarArt = new frmAgregarArticulo(this);
            frmAgregarArt.ShowDialog(this);     // Mostramos el formulario de forma modal.
        }

        private bool validateInformation()
        {
            if (cmbDoc.SelectedIndex == Constants.INVALID_ID || cmbMoneda.SelectedIndex == Constants.INVALID_ID ||
                cmbName.SelectedIndex == Constants.INVALID_ID || cmbTipoDoc.SelectedIndex == Constants.INVALID_ID)
            {
                MessageBox.Show(MessageConstants.MISSING_FIELDS, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            else if (_docDetails.Count == 0)
            {
                MessageBox.Show(MessageConstants.AT_LEAST_1_ITEM, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            return true;
        }

        private void btnAceptar_Click(object sender, EventArgs e)
        {
            BuySaleManager man = BuySaleManager.GetInstance();
            if(validateInformation())
            {
                int docId;
                if (cmbDoc.SelectedIndex > 0)
                    docId = BuySaleManager.GetInstance().GetDocumentFor(_documentCodes[cmbDoc.SelectedIndex], _docTypes[cmbDoc.SelectedIndex]).idDocumento;
                else
                    docId = Constants.INVALID_ID;
                bool result = man.SaveDocument(cmbTipoDoc.Text, _auxAccIds[cmbName.SelectedIndex], dateConta.Value,
                    dateEntrega.Value, _currencyIds[cmbMoneda.SelectedIndex], docId, _subTotalAmount,
                    _taxAmount, _totalAmount, _docDetails);
                if (result)
                {
                    MessageBox.Show(MessageConstants.DOCUMENT_INSERTION_SUCESS, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                    _docDetails = new List<DocDetail>();
                    updateTotals(-_taxAmount, -_subTotalAmount, MoneyManager.GetInstance().GetCurrency(_currencyIds[cmbMoneda.SelectedIndex]).Symbol);
                    gridArticulos.Rows.Clear();
                    cmbTipoDoc.SelectedIndex = 0;
                }
                else
                    MessageBox.Show(man.ErrorMessage, MessageConstants.TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void cmbDoc_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!cmbDoc.SelectedItem.ToString().Equals("Ninguno"))
            {
                btnAgregarArt.Enabled = false;
                btnEliminarArt.Enabled = false;
            }
            else
            {
                btnAgregarArt.Enabled = true;
                btnEliminarArt.Enabled = true;
            }
            fillPreviousDoc();
        }

        private void cmbTipoDoc_SelectedIndexChanged(object sender, EventArgs e)
        {
            cmbName.Items.Clear();
            fillComboBoxDocs(cmbTipoDoc.Text);
            fillComboProviderClient();
            cmbName.SelectedIndex = 0;
        }

        private void dateConta_ValueChanged(object sender, EventArgs e)
        {

        }

        private void cmbName_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void btnEliminarArt_Click(object sender, EventArgs e)
        {
            DeleteItem();
        }

        private void cmbMoneda_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbMoneda.SelectedIndex > Constants.INVALID_ID)
            {
                Currency currency = MoneyManager.GetInstance().GetCurrency(_currencyIds[cmbMoneda.SelectedIndex]);
                for(int rowIndex = 0; rowIndex < gridArticulos.Rows.Count - 1; rowIndex++) 
                {
                    DataGridViewRow row = gridArticulos.Rows[rowIndex];
                    row.Cells[Constants.UNIT_PRICE_INDEX].Value = currency.Symbol + row.Cells[Constants.UNIT_PRICE_INDEX].Value.ToString().Substring(1);
                    row.Cells[Constants.TOTAL_PRICE_INDEX].Value = currency.Symbol + row.Cells[Constants.TOTAL_PRICE_INDEX].Value.ToString().Substring(1);
                }
                txtAntesImp.Text = currency.Symbol + txtAntesImp.Text.Substring(1);
                txtMontoImp.Text = currency.Symbol + txtMontoImp.Text.Substring(1);
                txtTotal.Text = currency.Symbol + txtTotal.Text.Substring(1);
            }
        }
    }
}
